<template>
  <div ref="pixiContainer" class="pixi-container"></div>
</template>

<script setup>
import { onMounted, onBeforeUnmount, ref, watch, getCurrentInstance } from 'vue'
import { Application, Assets, Sprite, Graphics, Container, Text } from 'pixi.js';
import { store } from '../store/stroe';
import { EventManager } from '../utils/EventManager';

const pixiContainer = ref(null)
let eventManager = null;
let app = null;
// 存储高亮格子的容器
let highlightContainer = null;
//存储座位的容器
let seatContainer = null;

const cellSize = 40;

onMounted(() => {
    if (!pixiContainer.value) return
    store.value.PixiComponent = getCurrentInstance().exposed;
    init({});
})

onBeforeUnmount(() => {
    if (eventManager) {
        eventManager.destroy();
    }
    store.value.PixiComponent = null;
})
// 监听coordinates的变化
watch(() => store.value.coordinates, () => {
    if (app) {
        // 清空高亮格子和选中状态
        if (highlightContainer) {
            highlightContainer.removeChildren();
            store.value.selectedCells = store.value.selectedCells.filter(cell => cell.x < store.value.coordinates.x && cell.y < store.value.coordinates.y);
        
        }
        if(store.value.seatCells.length > 0){
            // 过滤超出范围的座位
            store.value.seatCells = store.value.seatCells.filter(cell => cell.x < store.value.coordinates.x && cell.y < store.value.coordinates.y);
        }
        // 清除旧的内容
        app.stage.removeChildren();
        // 重新绘制
        drawContent(app);
    }
}, { deep: true });

// 监听seatCells的变化
watch(() => store.value.seatCells, () => {
    if (app && seatContainer) {
        // 清空座位容器
        seatContainer.removeChildren();
        // 重新绘制座位
        drawSeats();
    }
}, { deep: true });

// 绘制座位的方法
function drawSeats() {
    store.value.seatCells.forEach(seat => {
        const seatGraphics = new Graphics()
            .beginFill(seat.color || 0x1DDCC2, 0.8) // 设置透明度为0.6
            .drawRect(seat.x * cellSize, seat.y * cellSize, cellSize, cellSize)
            .endFill();
        
        seatGraphics.zIndex = 1; // 设置与网格线相同的层级
        seatContainer.addChild(seatGraphics);
    });
}

async function init(options) {
    app = new Application();
    await app.init({ background: '#1099bb', resizeTo: pixiContainer.value });
    pixiContainer.value.appendChild(app.canvas);

    // 设置stage的变换原点为中心点
    app.stage.position.set(app.screen.width / 2, app.screen.height / 2);
    app.stage.pivot.set(app.screen.width / 2, app.screen.height / 2);
    // 启用舞台的子元素排序功能
    app.stage.sortableChildren = true;
    // 创建事件管理器实例
    eventManager = new EventManager(pixiContainer.value, app);
    drawContent(app);
}

/**
 * 创建高亮格子
 * @param {number} cellX - 格子X坐标
 * @param {number} cellY - 格子Y坐标
 * @returns {PIXI.Graphics} 高亮格子对象
 */
function createHighlightCell(cellX, cellY) {
    const highlight = new Graphics()
        .beginFill(0x00ff00, 0.5)
        .drawRect(cellX * cellSize, cellY * cellSize, cellSize, cellSize)
        .endFill();
    highlight.zIndex = 1;
    highlight.interactive = true;
    highlight.buttonMode = true;
    highlight.on('pointerdown', (event) => {
        if (eventManager) {
            eventManager.disable();
        }
        event.stopPropagation();
        highlightContainer.removeChild(highlight);
        highlight.destroy();
        store.value.selectedCells = store.value.selectedCells.filter(cell => !(cell.x === cellX && cell.y === cellY));
    });

    highlight.on('pointerup', (event) => {
        if (eventManager) {
            eventManager.enable();
        } 
    })
    return highlight;
}

/**
 * 绘制网格
 * @param {*} graphics
 * @returns
 * 
 */
function handleCellClick(cellX, cellY) {
    const existingIndex = store.value.selectedCells.findIndex(cell => 
        cell.x === cellX && cell.y === cellY
    );
    if (existingIndex === -1) {
        const highlight = createHighlightCell(cellX, cellY);
        highlightContainer.addChild(highlight);
        store.value.selectedCells.push({x: cellX, y: cellY});
        console.log(store.value.selectedCells);
    }
}

/**
 * 创建坐标轴文本
 * @param {string} textContent - 文本内容
 * @param {number} x - X坐标
 * @param {number} y - Y坐标
 * @param {object} style - 文本样式
 * @returns {PIXI.Text} 文本对象
 */
function createAxisText(textContent, x, y, style = { fontFamily: 'Arial', fontSize: 12, fill: 0xffffff }) {
    const text = new Text(textContent, style);
    text.position.set(x, y);
    return text;
}

/**
 * 绘制坐标轴
 * @param {PIXI.Container} coordContainer - 坐标容器
 * @param {number} x - X轴格子数量
 * @param {number} y - Y轴格子数量
 * @param {number} cellSize - 格子大小
 * @param {object} options - 配置选项
 * @param {number} options.offsetX - X轴偏移量
 * @param {number} options.offsetY - Y轴偏移量
 */

function drawCoordinates(coordContainer, x, y, cellSize, options = { offsetX: -20, offsetY: -20 }) {
    // 左边和上边的坐标
    coordContainer.position.set(options.offsetX, options.offsetY);
    
    // 绘制X轴坐标（上边）
    for (let i = 0; i < x; i++) {
        coordContainer.addChild(createAxisText(i.toString(), (i + 1) * cellSize, 0));
    }

    // 绘制Y轴坐标（左边）
    for (let j = 0; j < y; j++) {
        coordContainer.addChild(createAxisText(j.toString(), 0, (j + 1) * cellSize));
    }

    // 绘制X轴坐标（下边）
    for (let i = 0; i < x; i++) {
        coordContainer.addChild(createAxisText(i.toString(), (i + 1) * cellSize, (y + 1) * cellSize + options.offsetY + 5));
    }

    // 绘制Y轴坐标（右边）
    for (let j = 0; j < y; j++) {
        coordContainer.addChild(createAxisText(j.toString(), (x + 1) * cellSize + options.offsetX + 5, (j + 1) * cellSize));
    }
}

function buildGrid(graphics)
{
    const { x, y } = store.value.coordinates;
    const width = x * cellSize;
    const height = y * cellSize;

    // Draw filled rectangles for each cell
    for (let i = 0; i < x; i++) {
        for (let j = 0; j < y; j++) {
            const rect = graphics
                .beginFill(0xff0000)
                .drawRect(i * cellSize, j * cellSize, cellSize, cellSize)
                .endFill();
        }
    }

    // Draw vertical lines
    for (let i = 0; i <= x; i++)
    {
        graphics
            .moveTo(i * cellSize, 0)
            .lineTo(i * cellSize, height);
    }

    // Draw horizontal lines
    for (let i = 0; i <= y; i++)
    {
        graphics
            .moveTo(0, i * cellSize)
            .lineTo(width, i * cellSize);
    }

    // 在容器级别添加点击事件
    graphics.eventMode = 'static';
    // 拖拽相关变量
    let dragStartPos = null;
    let dragStartTime = 0;
    const DRAG_THRESHOLD = 5; // 拖拽阈值(像素)
    const CLICK_TIME_THRESHOLD = 200; // 点击时间阈值(毫秒)

    graphics.on('pointerdown', (event) => {
        if (event.data.button !== 0) return; // 只响应左键点击
        const localPos = event.data.getLocalPosition(graphics);
        const cellX = Math.floor(localPos.x / cellSize);
        const cellY = Math.floor(localPos.y / cellSize);
        
        if (eventManager) {
            eventManager.disable();
        }
        
        // 记录初始位置和时间
        dragStartPos = { x: event.clientX, y: event.clientY };
        dragStartTime = Date.now();
    });
    
    graphics.on('pointermove', (event) => {
        if (dragStartPos) {
            const dx = Math.abs(event.clientX - dragStartPos.x);
            const dy = Math.abs(event.clientY - dragStartPos.y);
            
            // 如果移动距离超过阈值，则标记为拖拽
            if (dx > DRAG_THRESHOLD || dy > DRAG_THRESHOLD) {
                dragStartPos = null;
            }
        }
    });
    
    graphics.on('pointerup', (event) => {
        if (event.data.button !== 0) return; // 只响应左键点击
        if (dragStartPos && (Date.now() - dragStartTime) < CLICK_TIME_THRESHOLD) {
            const localPos = event.data.getLocalPosition(graphics);
            const cellX = Math.floor(localPos.x / cellSize);
            const cellY = Math.floor(localPos.y / cellSize);
            handleCellClick(cellX, cellY);
        }
        dragStartPos = null;
        
        if (eventManager) {
            eventManager.enable();
        }
    });
    
    graphics.on('pointerup', () => {
        if (eventManager) {
            eventManager.enable();
        }
    });
    
    graphics.on('pointerupoutside', () => {
        if (eventManager) {
            eventManager.enable();
        }
    });

    return graphics;
}


// 添加矩形选择事件处理的公共方法，并在container和seatContainer上应用该方法
function addRectangleSelectionEvents(targetContainer) {
    let isDrawing = false;
    let startPos = null;
    let currentRect = null;

    targetContainer.eventMode = 'static';
    targetContainer.on('pointerdown', (event) => {
        if (eventManager) {
            eventManager.disable();
        }
        if (event.button !== 0) return;
        isDrawing = true;
        startPos = app.stage.toLocal(event.global);
        currentRect = drawRectangle(startPos.x, startPos.y, 0, 0, 0x000000);
    });

    targetContainer.on('pointermove', (event) => {
        if (!isDrawing) return;
        const currentPos = app.stage.toLocal(event.global);
        const width = currentPos.x - startPos.x;
        const height = currentPos.y - startPos.y;
        
        if (currentRect) {
            clearCurrentRectangle();
        }
        
        currentRect = drawRectangle(
            Math.min(startPos.x, currentPos.x),
            Math.min(startPos.y, currentPos.y),
            Math.abs(width),
            Math.abs(height),
            0x000000
        );
    });

    targetContainer.on('pointerup', (event) => {
        if (eventManager) {
            eventManager.enable();
        }
        if (event.button !== 0) return;
        if(currentRectangle){
            clearCurrentRectangle();
        }
        isDrawing = false;
        startPos = null;
        currentRect = null;
    });

    targetContainer.on('pointerupoutside', () => {
        if(currentRectangle){
            clearCurrentRectangle();
        }
        isDrawing = false;
        startPos = null;
        currentRect = null;
    });
}

//绘制内容方法
async function drawContent(app) {
    // 保存当前选中的格子信息
    const selectedCells = [...store.value.selectedCells];
    
    // 获取坐标信息
    const { x, y } = store.value.coordinates;
    const width = x * cellSize;
    const height = y * cellSize;
    
    // Create two grids - one with pixel-perfect lines and one without
    const gridPixel = buildGrid(new Graphics()).stroke({ color: 0xffffff, pixelLine: true, width: 5 });

    // Create a container to hold both grids
    const container = new Container();
    // Create a container for highlights
    highlightContainer = new Container();

    // 创建座位容器
    seatContainer = new Container();

    // 创建坐标容器
    const coordContainer = new Container();
    drawCoordinates(coordContainer, x, y, cellSize, { offsetX: -20, offsetY: -20 });

    container.addChild(gridPixel);
    container.addChild(seatContainer);
    container.addChild(coordContainer);
    container.addChild(highlightContainer);

 
    // Center the container on screen based on grid dimensions
    container.x = app.screen.width / 2 - width / 2;
    container.y = app.screen.height / 2 - height / 2;
    // 确保highlightContainer的位置与网格对齐
    highlightContainer.position.set(0, 0);
    
    // 过滤掉超出新网格范围的格子
    store.value.selectedCells = store.value.selectedCells.filter(cell => cell.x < x && cell.y < y);
    selectedCells.forEach(cell => {
        const highlight = createHighlightCell(cell.x, cell.y);
        highlightContainer.addChild(highlight);
    });
    app.stage.addChild(container);

    container.interactive = true;
    container.buttonMode = true;
    addRectangleSelectionEvents(container);

    seatContainer.interactive = true;
    seatContainer.buttonMode = true;
    addRectangleSelectionEvents(seatContainer);
}

// 当前矩形实例
let currentRectangle = null;

//绘制拖拽产生的矩形方法
function calculateSelectedCells(x, y, width, height) {
    const { x: gridX, y: gridY } = store.value.coordinates;
    const container = app.stage.children[0];
    
    // 考虑容器偏移量
    const adjustedX = x - container.x;
    const adjustedY = y - container.y;
    const adjustedWidth = width;
    const adjustedHeight = height;
    
    const startCellX = Math.max(0, Math.floor(adjustedX / cellSize));
    const startCellY = Math.max(0, Math.floor(adjustedY / cellSize));
    const endCellX = Math.min(gridX - 1, Math.floor((adjustedX + adjustedWidth) / cellSize));
    const endCellY = Math.min(gridY - 1, Math.floor((adjustedY + adjustedHeight) / cellSize));
    
    return {
        startCellX,
        startCellY,
        endCellX,
        endCellY,
        grid: container.children[0]
    };
}

/**
 * 存储矩形
 * @param {*} x 矩形左上角x坐标
 * @param {*} y 矩形左上角y坐标
 * @param {*} width 矩形宽度
 * @param {*} height 矩形高度
 */
function storeRectangle(x, y, width, height) {
    // 计算并选中覆盖的格子
    const { startCellX, startCellY, endCellX, endCellY, grid } = calculateSelectedCells(x, y, width, height);
    for (let i = startCellX; i <= endCellX; i++) {
        for (let j = startCellY; j <= endCellY; j++) {
            handleCellClick(i, j);
        }
    }
}

function drawRectangle(x, y, width, height, color) {
    clearCurrentRectangle();

    const rect = new Graphics()
       .beginFill(color,0.4)
       .drawRect(x, y, width, height)
       .endFill(); 
    
    rect.zIndex = 10; // 设置较高的zIndex确保显示在最上层
    app.stage.addChild(rect);
    currentRectangle = rect;
    
    storeRectangle(x, y, width, height);
}

// 清除当前矩形的方法
function clearCurrentRectangle() {
    if (currentRectangle) {
       
        app.stage.removeChild(currentRectangle);
        currentRectangle.destroy();
        currentRectangle = null;
    }
}

function clearAllHighlights() {
    // 销毁所有高亮层的子元素
    highlightContainer.children.forEach(child => {
        child.destroy();
    });
    // 清除所有高亮层
    highlightContainer.removeChildren();
    // 清空选中状态
    store.value.selectedCells = [];
}

//使用vue3暴漏出去的方法
defineExpose({
    drawContent,
    buildGrid,
    handleCellClick,
    calculateSelectedCells,
    clearCurrentRectangle,
    clearAllHighlights
});
</script>

<style scoped>
.pixi-container {
  width: 100%;
  height: 100%;
}
</style>

